import threading
import json
from django.contrib import auth
from django.core.mail import send_mail
from django.db import transaction
from django.db.models import Count, F
from django.db.models.functions import TruncMonth
from django.http import HttpResponse, JsonResponse
from django.shortcuts import render, redirect, reverse, get_object_or_404, get_list_or_404
from blog.Forms import UserForm
from django.contrib.auth import get_user_model
from blog.utils.validCode import get_validcode
from oldblog import settings

from blog.models import Article, Blog, Category, Tag, ArticleUpDown, Comment

User=get_user_model()
# Create your views here.


def hello(request):
    return HttpResponse('hello world')


def login(request):
    if request.method == 'POST':
        #print request.meth.POST 是不对的
        # print(request.POST)
        response={'user':None,'msg':None}
        user=request.POST.get('user')
        pwd=request.POST.get("pwd")
        valid_code=request.POST.get('valid_code')
        valid_code_str=request.session.get('valid_code_str')
        if valid_code.upper() == valid_code_str.upper():
            user=auth.authenticate(username=user,password=pwd)
            if user:
                #注册当前对象
                auth.login(request,user)
                response['user']=user.username
            else:
                response['msg']='username or password error!'
        else:
            response['msg']='valid code error!'
        return JsonResponse(response)

    return render(request,'login.html',locals())


def get_validcode_img(request):
    data = get_validcode(request)
    return HttpResponse(data)


def register(request):
    '''
    注册视图
    '''
    if request.method == "POST":
        # print(request.POST)
        form = UserForm(request.POST)
        # 需要使用json返回的数据
        response = {"user": None, "msg": None}
        if form.is_valid():
            # form表单所有的干净信息
            # print(form.cleaned_data)
            response['user'] = form.cleaned_data.get('user')
            # response['msg']='sucessful'
            # 生成一条用户记录
            username = form.cleaned_data.get('user')
            pwd = form.cleaned_data.get('re_pwd')
            email = form.cleaned_data.get('email')
            # 接受上传的文件对象
            avatar_obj = request.FILES.get('avatar')
            # print(avatar_obj)
            # 将文件对象赋值给avatar属性
            extra = {}
            if avatar_obj:
                extra['avatar'] = avatar_obj
            # 此外应该加一个异常处理,万一生成不成功呢
            User.objects.create_user(username=username, password=pwd, email=email, **extra)
        else:
            # form表单所有的错误信息
            # print(form.errors)
            response['msg'] = form.errors
        return JsonResponse(response)
    form = UserForm()
    return render(request, 'register.html', locals())


def index(request):
    article_list= Article.objects.all()
    # print(article_list)
    return render(request,'index.html',locals())


def logout(request):
    #注销用户，等同于request.session.flush()
    auth.logout(request)
    return redirect("/login/")


def get_classification_data(username):
    user = User.objects.filter(username=username).first()
    if not user:
        return None
    blog = user.blog
    article_list = Article.objects.filter(user=user).all()
    cate_list = Category.objects.filter(blog=blog).values("pk"). \
        annotate(c=Count("article__title")).values_list("title", 'c')
    # print(article,blog)
    tag_list = Tag.objects.filter(blog=blog).values("pk"). \
        annotate(c=Count("article__title")).values_list("title", 'c')
    article_month_count = article_list.annotate(month=TruncMonth('create_time')).values('month'). \
        annotate(c=Count('nid')).values_list('month', 'c').order_by()
    return {'blog': blog, 'user': user, 'article_list': article_list, 'tag_list': tag_list, 'cate_list': cate_list,
            'article_month_count': article_month_count}


def home_site(request,username,**kwargs):
    '''
    个人站点首页
    '''
    # user=get_object_or_404(User,username=username)
    # print(username)
    # print(kwargs)
    user = User.objects.filter(username=username).first()
    if not user:
        return render(request, 'not_found.html')

    #当前用户站点的所有文章都拿出来
    blog=user.blog
    article_list = Article.objects.filter(user=user).all()
    #别一种查询方法
    # article_list= Article.objects.filter(user=user)
    # print(blog,article_list)
    # 第一个后的表模型.objects.values('pk').annotate(聚合函数（关联表__统计字段）).value("表模型的所有字段以及统计字段")
    # 最后的函数 可以是values()也可以是values_list(),前者返回字典，后者返回列表
    # ret = Category.objects.values("pk").annotate(c=Count("article__title")).values("title", 'c')
    # print(ret)
    # 查询当前站点每一个分类以及对应的文章数
    cate_list = Category.objects.filter(blog=blog).values("pk").\
        annotate(c=Count("article__title")).values_list("title", 'c')
    # print("cate list is",cate_list)



    # 查询当前站点每一个标签以及对应的文章数
    tag_list = Tag.objects.filter(blog=blog).values("pk").\
        annotate(c=Count("article__title")).values_list("title", 'c')
    # print("tag list is", tag_list)


    # 查询当前站点每一年月的名称以及对应的文章数
    # 方式1 django 自带的功能实现分月汇总,好像实现不了。
    # article_month_list = Article.objects.filter(user=user).values("create_time_month").\
    #     annotate(c=Count("create_time__year_month")).values_list("create_time__year_month",'c')
    # print(article_month_list)
    #extra()函数,注入sql语句，自定义查询条件
    # query_result=Article.objects.extra(select={"is_rencent":"create_time >'2019-10-01'"}).values('title','is_rencent')
    # print(query_result)
    #方式2 利用extra函数实现分类汇总
        # article_month_list = Article.objects.filter(user=user).\
        #     extra(select={"month_date":"date_format(create_time,'%%Y/%%m')"}).values('title','month_date').\
        #     annotate(c=Count("nid")).values('month_date','c')
        # print(article_month_list)

    #方式3 TruncMonth filter(user=user).
    #最后要加一个order_by(),进行
    article_month_count = article_list.annotate(month=TruncMonth('create_time')).values('month').\
        annotate(c=Count('nid')).values_list('month','c').order_by()
    # print(article_month_count)
    if kwargs:
        condition = kwargs.get("condition")
        param = kwargs.get("param")
        if condition == "category":
            article_list=article_list.filter(category__title=param).all()
            # print(article_list)
        elif condition == "tag":
            article_list=article_list.filter(user=user).filter(tags__title=param).all()
            # print(article_list)
        elif condition =='archive':
            year, month = param.split("-")[0:2]
            article_list = article_list.filter(create_time__year=year,create_time__month=month).all()
            # print(article_list)
        else:
            pass

    return render(request,'home_site.html',locals())


def article_detail(request, username, pk):
    user = User.objects.filter(username=username).first()
    if not user:
        return render(request,'not_found.html')
    article = Article.objects.filter(user=user).filter(pk=pk).first()
    comment_list = Comment.objects.filter(article=article).all()
    # print(context)
    # 下面学习include tag
    # 新建templatetags 包,生成一个文件my_tags.py,然后写具体的函数
    # 使用时在模板文件中，{% load my_tags %}


    return render(request, 'article_detail.html', locals())


def digg(request):
    response={'state':True}
    if request.method=="POST":
        #将ajax提供过来的字符串反序列化为python bool类型
        is_up = json.loads(request.POST.get("is_up"))
        article_id=request.POST.get("article_id")
        user=request.user
        # print(is_up,article_id,user,type(is_up))
        ret = ArticleUpDown.objects.filter(user=user,article_id=article_id).first()
        if not ret:
            #如果以前没点赞过
            # 为点赞表插入数据
            ard = ArticleUpDown.objects.create(user=user, article_id=article_id, is_up=is_up)
            # 同步更新Article 的点赞数量
            if is_up:
                Article.objects.filter(pk=article_id).update(up_count=F("up_count") + 1)
            else:
                Article.objects.filter(pk=article_id).update(down_count=F("down_count") + 1)
        else:
            response['msg'] = '您已经操作过了'
            response['state'] = False
            response['handled'] = ret.is_up
    return JsonResponse(response)


def get_comment_tree(request):
    article_id = request.GET.get("article_id")
    ret = Comment.objects.filter(article_id=article_id).values("pk", "content", "user__username", "create_time",
                                                               "parent_comment_id").order_by("pk")
    # # 将时间格式处理成字符串
    # #第一种
    for i in ret:
        i["create_time"] = i["create_time"].strftime("%Y-%m-%d %X")
    ret = list(ret)

    # 第二种原生语句查询

    # 为了能将一个非字典的对象序列化，需要加safe参数为False
    return JsonResponse(ret, safe=False)


def comment(request):
    if request.method == "POST":
        article_id = request.POST.get("article_id")
        pid = request.POST.get("pid")
        # print(pid,type(pid))
        content = request.POST.get("content")
        user_id = request.user.pk
        # print(article_id,type(pid),content,user_id)
        # 事务操作
        article_obj = Article.objects.filter(pk=article_id).first()
        with transaction.atomic():
            comment_obj = Comment.objects.create(user_id=user_id, article_id=article_id,
                                                 parent_comment_id=pid, content=content)
            # 文章的评论数要加1
            article_obj.comment_count += 1
            comment_obj.save()

        # 当有用户新评论时，发送邮件给这篇文章的作者
        # send_mail(
        #     "您的文章%s新增了一条评论内容"%article_obj.title,
        #     content,
        #     settings.EMAIL_HOST_USER,
        #     #文章作者
        #     # article_obj.user.email
        #     ['liangfuting@cnpiec.com.cn']
        #
        # )
        # 用线程来发送邮件，不占用主进程时间

        t = threading.Thread(target=send_mail, args=(
            "您的文章%s新增了一条评论内容" % article_obj.title,
            content,
            settings.EMAIL_HOST_USER,
            # 文章作者
            # article_obj.user.email
            ['liangfuting@cnpiec.com.cn', ]
        ))
        t.start()

        if pid:
            parent_comment = comment_obj.parent_comment
            response = {
                # datetime要进行转换后，才能通过json输出
                'create_time': comment_obj.create_time.strftime("%Y-%m-%d %X"),
                "username": request.user.username,
                'content': comment_obj.content,
                'parent_comment': parent_comment.content,
                'parent_comment_user': parent_comment.user.username

            }
        else:
            response = {
                # datetime要进行转换后，才能通过json输出
                'create_time': comment_obj.create_time.strftime("%Y-%m-%d %X"),
                "username": request.user.username,
                'content': comment_obj.content,
                'parent_comment': "",
                'parent_comment_user': ""

            }

        # print(response)
        return JsonResponse(response)
